package com.fang.common.request;

import com.fang.common.exception.NetworkDiskException;
import com.fang.common.util.JWTUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

/**
 * @author Bernie_fang
 * @Description:
 * @create 2021/9/16 11:07
 **/
@Component
public class FluxBaseController {

    /*
    修改说明
        1使用ServerWebExchange代替HttpServletRequest和HttpServletResponse：
        ServerWebExchange是Spring WebFlux中用于处理请求和响应的核心对象。
        通过ServerWebExchange可以获取请求头、参数、会话等信息。
        2使用响应式API：
        将方法返回值改为Mono类型，以支持异步和响应式处理。
        使用Mono.fromCallable将同步操作包装为响应式操作。
        3会话管理：
        使用serverWebExchange.getSession()获取会话信息，并将其转换为传统的HttpSession对象。
        4异常处理：
        在响应式编程中，异常处理通常通过onErrorResume或直接在流中抛出异常来实现。
        5移除@Controller注解：
        在WebFlux中，控制器通常使用@RestController或@Controller注解，但这里的BaseController是一个基础类，因此使用@Component注解使其成为一个Spring托管的组件。
    * */

    @Resource
    private ServerWebExchange serverWebExchange;

    public ServerWebExchange getServerWebExchange() {
        return serverWebExchange;
    }

    public Mono<ServerRequest> getServerRequest() {
        return Mono.just(ServerRequest.create(serverWebExchange, null));
    }

    public Mono<HttpSession> getSession() {
        return serverWebExchange.getSession()
                .map(webSession -> (HttpSession) webSession.getAttribute("httpSession"))
                .defaultIfEmpty((HttpSession) serverWebExchange.getAttribute("httpSession"));
    }

    protected String getToken() {
        String token = serverWebExchange.getRequest().getHeaders().getFirst("Authorization");
        if (StringUtils.isEmpty(token)) {
            throw new NetworkDiskException("Authorization header is missing or empty");
        }
        return token;
    }

    protected String getAuthorId() throws NetworkDiskException {
        String token = getToken();
        String authorId = JWTUtil.getUserId(token);
        return authorId;
    }
}
